#pragma once

// Dependencies
#include "Vector2.h"
#include "Point2.h"
#include <vector>

// Polygon2
// Represents a list of connected vertices, their edges, and their normals
template<class T>
class Contour2_t {
public: // Typedefs
	typedef T value_type;
	typedef Contour2_t<T> this_type;
	typedef Point2_t<T> point_type;
	typedef Vector2_t<T> vector_type;
	typedef std::vector<point_type> point_array_type; 
	typedef std::vector<vector_type> vector_array_type;

public: // Helper structures
	// VertexLock
	// Provides access to a polygon's vertices, and updates normals after use
	class VertexLock {
	public: // Constructors/Destructor
		VertexLock( this_type& poly );
		~VertexLock();

	public: // Operators
		point_array_type& vertices();
		
	public: // Members
		this_type& target;
	};

public: // Constructors
	Contour2_t();

	template<class InputIterator>
	Contour2_t( InputIterator begin, InputIterator end ) {
		assign( begin, end );
	}

public: // Methods
	template<class InputIterator>
	void assign( InputIterator begin, InputIterator end ) {
		mVertices.assign( begin, end );
		recalculateNormals();
	}

	void recalculateNormals();
	Point2_t<T> center() const;

public: // Mutators
	// Calling vertices with the intent of modifying the polygon will return a VertexLock object, which
	// allows access to the polygon's mVertices.  Once the lock falls out of scope (i.e. finished modifying
	// vertices), the lock will call recalculateNoramls()
	VertexLock lockVertices();

public: // Accessors
	const point_array_type& vertices() const;
	const vector_array_type& edgeNormals() const;
	const vector_array_type& vertexNormals() const;

private: // Members
	point_array_type mVertices;
	vector_array_type mEdgeNormals;
	vector_array_type mVertexNormals;

private: // Friends
	friend class VertexLock;
};

typedef Contour2_t<float> Contour2f;
typedef Contour2_t<double> Contour2;